package com.xinyuan.digit.next.subscriber.db.util;

import com.xinyuan.digit.next.subscriber.db.pojo.SFunction;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;

/**
 * Lambda工具类
 *
 * @author LiuChenghui 2025/10/23 11:46:00
 * @version 1.0
 */
public class LambdaUtils {
    /**
     * 获取属性名称
     *
     * @param func
     * @param <T>
     * @return
     */
    private static <T> String getPropertyName(SFunction<T, ?> func) {
        try {
            Method writeReplace = func.getClass().getDeclaredMethod("writeReplace");
            writeReplace.setAccessible(true);
            SerializedLambda serializedLambda = (SerializedLambda) writeReplace.invoke(func);
            String methodName = serializedLambda.getImplMethodName();

            if (methodName.startsWith("get")) {
                return methodName.substring(3);
            } else if (methodName.startsWith("is")) {
                return methodName.substring(2);
            }
            return methodName;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取属性名称并驼峰转下划线
     *
     * @param func
     * @param <T>
     * @return
     */
    public static <T> String column(SFunction<T, ?> func) {
        String propertyName = getPropertyName(func);
        return camelToUnderline(propertyName);
    }

    /**
     * 驼峰转下划线
     *
     * @param camelCase
     * @return
     */
    public static String camelToUnderline(String camelCase) {
        String res = camelCase.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
        res = "\"" + res + "\"";  //解决属性是SQL关键字问题
        return res;
    }

    /**
     * 对象转下划线 BaseDaoProvider => base_dao_provider
     */
    public static String classToLine(Class clazz) {
        return camelToUnderline(clazz.getSimpleName());
    }

    public static <T> Class<T> getEntityClass(SFunction<T, ?> lambda) {
        try {
            SerializedLambda serializedLambda = getSerializedLambda(lambda);
            String className = serializedLambda.getImplClass().replace("/", ".");
            return (Class<T>) Class.forName(className);
        } catch (Exception e) {
            throw new RuntimeException("获取实体类类型失败", e);
        }
    }

    private static SerializedLambda getSerializedLambda(SFunction<?, ?> lambda) throws Exception {
        // 检查是否为代理类
        Class<?> clazz = lambda.getClass();
        if (!clazz.isSynthetic()) {
            throw new RuntimeException("不是合法的Lambda表达式");
        }
        // 通过writeReplace方法获取SerializedLambda
        Method writeReplace = clazz.getDeclaredMethod("writeReplace");
        writeReplace.setAccessible(true);
        return (SerializedLambda) writeReplace.invoke(lambda);
    }


    /**
     * 首字母转小写
     */
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0))) return s;
        else return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }
}
